/**
 * Copyright (C) 2007 The AsyncMail Group <asyncmail@googlegroups.com>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *         http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.asyncmail.common;

import org.apache.commons.logging.Log;
import org.springframework.beans.factory.annotation.Required;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class WiringContainer {
    private List<Object> handlers = new LinkedList<Object>();

    private Log logger = null;

    public void initialize() throws Exception {
        wireExtensibleHandlers();
    }

    /**
     * ExtensibleHandler wiring
     * 
     * @throws WiringException
     */
    private void wireExtensibleHandlers() throws WiringException {
        for (Iterator<Object> h = handlers.iterator(); h.hasNext();) {
            Object handler = h.next();
            if (handler instanceof ExtensibleHandler) {
                List<Class<?>> markerInterfaces = ((ExtensibleHandler) handler)
                        .getMarkerInterfaces();
                for (int i = 0; i < markerInterfaces.size(); i++) {
                    Class<?> markerInterface = markerInterfaces.get(i);
                    List<Object> extensions = getHandlers(markerInterface);
                    getLogger().debug(
                            "Wiring " + markerInterface.getSimpleName()
                                    + " => " + extensions);
                    ((ExtensibleHandler) handler).wireExtensions(
                            markerInterface, extensions);
                }
            }
        }
    }

    /**
     * Returns a list of handler of the requested type.
     * 
     * @param type
     *                the type of handler we're interested in
     * @return a List of handlers
     */
    public LinkedList<Object> getHandlers(Class<?> type) {
        LinkedList<Object> result = new LinkedList<Object>();
        for (Iterator<Object> i = handlers.iterator(); i.hasNext();) {
            Object handler = i.next();
            if (type.isInstance(handler)) {
                result.add(handler);
            }
        }
        return result;
    }

    public List<Object> getHandlers() {
        return handlers;
    }

    public void setHandlers(List<Object> handlers) {
        this.handlers = handlers;
    }

    public Log getLogger() {
        return logger;
    }

    @Required
    public void setLogger(Log logger) {
        this.logger = logger;
    }

}
